Skip to content

feat(zoo-gateway): settings UI, validation, and i18n#345

Merged
JamesRobert20 merged 15 commits into
mainfrom
feat/zoo-gateway-settings-ui
Jun 3, 2026
Merged

feat(zoo-gateway): settings UI, validation, and i18n#345
JamesRobert20 merged 15 commits into
mainfrom
feat/zoo-gateway-settings-ui

Conversation

@JamesRobert20
Copy link
Copy Markdown
Contributor

@JamesRobert20 JamesRobert20 commented May 27, 2026

Summary

  • Adds ZooGateway settings component, provider wiring in ApiOptions, and sign-in validation
  • Initializes zooGatewayModelId when switching to Zoo Gateway
  • Adds i18n strings across locales (including formal Turkish validation copy)

Part 2 of the Zoo Gateway stack. Depends on #344.

Test plan

  • webview-ui: ApiOptions, validate tests
  • Manual: select Zoo Gateway, sign-in prompt, model picker

Made with Cursor

Summary by CodeRabbit

  • New Features
    • Zoo Gateway provider added to API settings with sign-in/account UI, automatic model selection, and settings integration
    • Provider docs and model-default resolution unified for consistent behavior
  • Validation / Bug Fixes
    • Form validation updated to avoid duplicate Zoo Gateway sign-in errors and respect auth state in welcome flow
  • Tests
    • New/updated tests covering Zoo Gateway, validation, and API fetch robustness
  • Localization
    • Zoo Gateway strings added across many locales (17+)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d2067bb7-e23f-4e19-a69b-7e070a638c46

📥 Commits

Reviewing files that changed from the base of the PR and between 5aa42cc and 2fbf902.

📒 Files selected for processing (30)
  • src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts
  • webview-ui/src/components/settings/ApiOptions.tsx
  • webview-ui/src/components/settings/ModelPicker.tsx
  • webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx
  • webview-ui/src/components/settings/constants.ts
  • webview-ui/src/components/settings/providers/ZooGateway.tsx
  • webview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsx
  • webview-ui/src/components/settings/providers/index.ts
  • webview-ui/src/components/settings/utils/providerModelConfig.ts
  • webview-ui/src/components/welcome/WelcomeViewProvider.tsx
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/pl/settings.json
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/ru/settings.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
  • webview-ui/src/utils/__tests__/validate.spec.ts
  • webview-ui/src/utils/validate.ts
✅ Files skipped from review due to trivial changes (10)
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/ru/settings.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
🚧 Files skipped from review as they are similar to previous changes (18)
  • webview-ui/src/components/settings/constants.ts
  • webview-ui/src/components/settings/providers/index.ts
  • webview-ui/src/components/settings/tests/ApiOptions.spec.tsx
  • webview-ui/src/components/welcome/WelcomeViewProvider.tsx
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/components/settings/ModelPicker.tsx
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/utils/tests/validate.spec.ts
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/components/settings/ApiOptions.tsx
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/utils/validate.ts
  • webview-ui/src/components/settings/providers/tests/ZooGateway.spec.tsx
  • webview-ui/src/components/settings/utils/providerModelConfig.ts
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/components/settings/providers/ZooGateway.tsx

📝 Walkthrough

Walkthrough

Adds a Zoo Gateway provider: new ZooGateway settings component and default-model selector, ApiOptions wiring and docs/model helper, auth-aware validation changes, tests for component/validation/fetcher, and localization entries across languages.

Changes

Zoo Gateway Provider Settings Integration

Layer / File(s) Summary
Provider metadata and helper registry
webview-ui/src/components/settings/utils/providerModelConfig.ts, webview-ui/src/components/settings/constants.ts, webview-ui/src/components/settings/ModelPicker.tsx, webview-ui/src/components/settings/providers/index.ts
Add provider model/docs helpers and registry (getProviderModelConfig, getProviderDocsSlug), add zoo-gateway to PROVIDERS, widen ModelPicker prop to accept zooGatewayModelId, and re-export ZooGateway.
ZooGateway component and default model selection
webview-ui/src/components/settings/providers/ZooGateway.tsx
Add pickZooGatewayDefaultModelId (prefers Claude Sonnet 4.5/4 patterns) and ZooGateway component that reads auth state, builds auth/dashboard URLs, derives router models, and auto-sets zooGatewayModelId when missing or stale; renders account panel and ModelPicker.
ZooGateway tests
webview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsx
Unit tests for default-model selection and component tests covering initialization, stale-id correction, no-op cases, loading state, and sign-in validation rendering with supporting mocks.
ApiOptions integration and provider switching
webview-ui/src/components/settings/ApiOptions.tsx, webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx
Import and mount ZooGateway; switch provider model/docs lookup to use getProviderModelConfig/getProviderDocsSlug; bypass generic error path for zoo-gateway; add test ensuring provider switch seeds zooGatewayModelId.
Validation and WelcomeView wiring
webview-ui/src/utils/validate.ts, webview-ui/src/utils/__tests__/validate.spec.ts, webview-ui/src/components/welcome/WelcomeViewProvider.tsx
Thread zooCodeIsAuthenticated into validation; validateModelsAndKeysProvided returns validation.zooGatewaySignIn only when zooSessionToken missing and not authenticated; validateApiConfigurationExcludingModelErrors skips zoo-gateway sign-in errors for form entry; WelcomeView passes auth state; tests cover combinations.
Internationalization
webview-ui/src/i18n/locales/*/settings.json
Add providers.zooGateway account/sign-in/authenticated strings and validation.zooGatewaySignIn to locale files across many languages.
Fetcher test mock
src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts
Mock zoo-code-auth to return deterministic values for fetcher tests; new test asserts structurally unexpected Axios responses return {} and log an error.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ApiOptions
  participant ZooGateway
  participant useExtensionState
  participant pickZooGatewayDefaultModelId
  participant setApiConfigurationField
  participant ModelPicker
  User->>ApiOptions: select provider zoo-gateway
  ApiOptions->>ZooGateway: mount ZooGateway with props
  ZooGateway->>useExtensionState: read zooCodeIsAuthenticated, zooSessionToken, dashboardBaseUrl
  ZooGateway->>pickZooGatewayDefaultModelId: compute resolved default from routerModels["zoo-gateway"]
  pickZooGatewayDefaultModelId-->>ZooGateway: defaultModelId
  ZooGateway->>setApiConfigurationField: set zooGatewayModelId if missing/stale
  ZooGateway->>ModelPicker: render with available models and selected/default id
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • navedmerchant
  • hannesrudolph
  • edelauna

"I hopped through code and found a key,
OAuth in paws, models by Sonnet's might,
Across many tongues we sign in free,
Settings sprout wings in morning light. 🐰"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main addition of Zoo Gateway settings UI, validation, and internationalization support across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/zoo-gateway-settings-ui

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

webview-ui/src/components/settings/ApiOptions.tsx

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

webview-ui/src/components/settings/ModelPicker.tsx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

  • 9 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@JamesRobert20 JamesRobert20 mentioned this pull request May 27, 2026
1 task
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-types-core branch from f776483 to dfb1eed Compare May 27, 2026 14:23
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch 2 times, most recently from 8634510 to 7bc8c0c Compare May 27, 2026 14:42
@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@proyectoauraorg proyectoauraorg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Settings UI, Validation, and i18n

Verdict: ✅ Approved

Verified

  • ApiOptions.spec.tsx — 18 tests pass (including zoo-gateway modelId initialization)
  • validate.spec.ts — 20 tests pass
  • ZooGateway.tsx — clean component following existing provider pattern
  • validate.ts — requires authentication before use (good UX gate)
  • ✅ i18n — all 18 locales covered

Notes

  • vite.config.ts has +56/-11 changes — verified it doesn't break other providers
  • WelcomeViewProvider.tsx integration looks correct for onboarding flow
  • i18n keys id and nl have slightly fewer changes (+9/-1 vs +11/-3) — appears intentional

Dependency

Depends on #344. After #344 merges, this should rebase cleanly.

@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch 2 times, most recently from a40f6e9 to 983c133 Compare May 28, 2026 21:19
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-types-core branch from 6f2b189 to 2ae4393 Compare May 29, 2026 02:55
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch 2 times, most recently from 6ae680e to 946d6d1 Compare May 29, 2026 03:15
Copy link
Copy Markdown
Contributor

@edelauna edelauna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice first pass! Had some feedback to prevent threading a boolean through layers.

Thanks again for breaking this up, makes review much faster / easier.


const WelcomeViewProvider = () => {
const { apiConfiguration, currentApiConfigName, setApiConfiguration, uriScheme } = useExtensionState()
const { apiConfiguration, currentApiConfigName, setApiConfiguration, uriScheme, zooCodeIsAuthenticated } =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deeper issue is that threading zooCodeIsAuthenticated through validation, props, and useCallback deps is a smell — it's caused by auth state living in two places (ProviderSettings.zooSessionToken and the SecretStorage cache) with no sync step between them.

VS Code has a first-class API for exactly this: vscode.authentication.registerAuthenticationProvider. Registering a provider means any caller — validation, handlers, UI — just asks VS Code for the session:

const session = await vscode.authentication.getSession('zoo-code', [], { createIfNone: false })
if (!session) return i18next.t('settings:validation.zooGatewaySignIn')

This eliminates the threading entirely:

  • Single source of truth — no split between profile token and cached token
  • onDidChangeSessions fires automatically on sign-in/out, no manual state propagation needed
  • Validation reads only ProviderSettings like every other provider
  • VS Code's native Accounts menu (bottom-left status bar) handles sign-out for free

Comment on lines +135 to +137
case "zoo-gateway":
if (!apiConfiguration.zooSessionToken && !zooCodeIsAuthenticated) {
return i18next.t("settings:validation.zooGatewaySignIn")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this branch covered in validate.spec.ts? I only see "zoo-gateway": {} in the mock data — are there tests for the three paths: (1) no token + zooCodeIsAuthenticated false → error, (2) zooSessionToken set → ok, (3) no token but zooCodeIsAuthenticated: true → ok?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests added in f6aae3c (validate.spec.ts):

  • validateApiConfiguration suite: (1) no token + zooCodeIsAuthenticated false returns settings:validation.zooGatewaySignIn, (2) no token + auth true returns undefined, (3) zooSessionToken set + auth false returns undefined.
  • validateApiConfigurationExcludingModelErrors suite: confirms the form-level path now no-ops for zoo-gateway regardless of token/auth state, since the inline <ApiErrorMessage> in ZooGateway.tsx owns that UX (see the related thread on ApiOptions.tsx).

Comment on lines +95 to +99
<a
href={authUrl}
className="inline-flex w-fit items-center rounded-sm bg-vscode-button-background px-3 py-1 text-xs text-vscode-button-foreground no-underline hover:bg-vscode-button-hoverBackground">
{t("settings:providers.zooGateway.signInButton")}
</a>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other providers with auth links use VSCodeButtonLink (e.g. OpenRouter.tsx and OpenCodeGo.tsx). Would <VSCodeButtonLink href={authUrl} appearance="primary"> work here to keep the pattern consistent?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already on VSCodeButtonLink in this file (the sign-in CTA at the bottom of the unauthenticated branch uses <VSCodeButtonLink href={authUrl} appearance="primary">). After f6aae3c the unauthenticated card stacks: inline <ApiErrorMessage> for the validation error, the existing description, then the same <VSCodeButtonLink>, which matches the OpenRouter/OpenCodeGo pattern.

Comment thread webview-ui/vite.config.ts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should be reverted — it's not related to zoo-gateway and it conflicts with #214 (chore(webview): migrate build to Vite 8), which deliberately introduced rolldownOptions, tsconfigPaths, and the simplified chunk config three days ago. This commit appears to have been authored against a stale working tree that predated that merge.

@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch from 2dde8b5 to 7a25767 Compare May 30, 2026 16:24
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-types-core branch from f067b91 to 9b56ac8 Compare May 30, 2026 16:36
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch 2 times, most recently from f780a86 to d1e8b1c Compare May 31, 2026 00:43
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-types-core branch from 8b677df to 9e8bab3 Compare May 31, 2026 01:04
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch from d1e8b1c to 2e677ba Compare May 31, 2026 01:04
Copy link
Copy Markdown
Contributor

@taltas taltas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One larger comment

simplifySettings?: boolean
}

function isSonnet45ModelId(id: string) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not your fault because it's the standard, but putting numbers for function names feels so so wrong 😂😂

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, baking the version into the helper name was awkward. Renamed to isClaudeSonnetModelId in f6aae3c, with the version-priority chain (4.5 exact, 4.5 substring, 4.5 dash variant, 4 family, first sonnet) expressed directly inside pickZooGatewayDefaultModelId. The helper now just answers "is this a Claude Sonnet of any version".

organizationAllowList,
setErrorMessage,
isRetiredSelectedProvider,
zooCodeIsAuthenticated,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @edelauna mentioned below, we should be wary of pumping zooCodeIsAuthenticated in the useEffect here as well. , I don't think we should be pumpingzooCodeIsAuthenticated here in the useEffect through here. if you remove it, then add

+		if (apiConfiguration.apiProvider === "zoo-gateway") {
+			setErrorMessage(undefined)
+			return
+		}

You will get a generic error message if something goes wrong.

If you want to add specific error messaging you can add it on the UI side in webview-ui/src/components/settings/providers/ZooGateway.tsx with ApiErrorMessage component

+import { ApiErrorMessage } from "../ApiErrorMessage"
@@
				{!zooCodeIsAuthenticated ? (
					<div className="flex flex-col gap-1">
+						<ApiErrorMessage errorMessage={t("settings:validation.zooGatewaySignIn")} />
						<p className="text-xs text-vscode-descriptionForeground">
							{t("settings:providers.zooGateway.signInDescription")}
						</p>
						<VSCodeButtonLink href={authUrl} appearance="primary">
							{t("settings:providers.zooGateway.signInButton")}
						</VSCodeButtonLink>
					</div>
				) : (

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in f6aae3c, taking your suggestion exactly:

  1. ApiOptions.tsx short-circuits zoo-gateway in the validation effect and clears the error, so zooCodeIsAuthenticated no longer needs to be in the dep list.
  2. validateApiConfigurationExcludingModelErrors returns undefined for zoo-gateway entirely, so the form-level path stops carrying auth state.
  3. ZooGateway.tsx renders the sign-in error inline using <ApiErrorMessage errorMessage={t("settings:validation.zooGatewaySignIn")} /> above the existing description + sign-in button.

validateApiConfiguration (the welcome-view entry point) still threads zooCodeIsAuthenticated since the welcome screen does need to gate "Get Started" on auth state, and validate.spec.ts was reorganized so the three zoo-gateway branches (no token + unauth, no token + auth, token set) now exercise that entry point, with a separate suite asserting the form-level path no-ops for zoo-gateway.

React 19.2's useEffectEvent would be the textbook fit here, but webview-ui is still on React 18.3.1, so this approach is the closest equivalent until we upgrade.

@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch 3 times, most recently from f6aae3c to e2e4536 Compare June 1, 2026 14:26
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-types-core branch from 2f9a5a0 to 5e6c278 Compare June 1, 2026 14:26
Copy link
Copy Markdown
Contributor

@taltas taltas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One other thing I noticed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not your fault, but I think we should replace this entire thing in with a separate file, the ApiOptions file is geting pretty long. Something like

const config = PROVIDER_UI_REGISTRY[value]?.modelConfig
const name = PROVIDER_UI_REGISTRY[selectedProvider]?.label
const slug = PROVIDER_UI_REGISTRY[selectedProvider]?.docsSlug || selectedProvider

Plus a new file with all the config:

export const PROVIDER_UI_REGISTRY = {
  "zoo-gateway": {
    label: "Zoo Gateway",
    docsSlug: "zoo-gateway",
    modelConfig: { field: "zooGatewayModelId", default: zooGatewayDefaultModelId },
  },
  ...
} satisfies Partial<Record<ProviderName, {
  label: string
  docsSlug?: string
  modelConfig?: { field: keyof ProviderSettings; default?: string }
}>>

Base automatically changed from feat/zoo-gateway-types-core to main June 2, 2026 13:25
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch from e2e4536 to babbe9e Compare June 2, 2026 13:55
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
webview-ui/src/components/welcome/WelcomeViewProvider.tsx (1)

23-36: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Thread zooCodeIsAuthenticated through getWelcomeApiConfiguration to avoid dropping authenticated zoo-gateway

getWelcomeApiConfiguration calls validateApiConfiguration(apiConfiguration) without the 4th zooCodeIsAuthenticated argument. In validateApiConfiguration’s zoo-gateway branch, the function returns the settings:validation.zooGatewaySignIn error when apiConfiguration.zooSessionToken is missing and zooCodeIsAuthenticated is falsy/undefined—so the helper falls back to DEFAULT_WELCOME_API_CONFIGURATION (OpenRouter). This impacts both the initial effectiveApiConfiguration and the initialApiConfiguration used when starting the flow.

🛠️ Proposed direction

Thread the auth flag through the helper:

-const getWelcomeApiConfiguration = (apiConfiguration?: ProviderSettings): ProviderSettings => {
+const getWelcomeApiConfiguration = (
+	apiConfiguration?: ProviderSettings,
+	zooCodeIsAuthenticated?: boolean,
+): ProviderSettings => {
 	if (!apiConfiguration?.apiProvider) {
 		return DEFAULT_WELCOME_API_CONFIGURATION
 	}
 
-	const validationError = validateApiConfiguration(apiConfiguration)
+	const validationError = validateApiConfiguration(apiConfiguration, undefined, undefined, zooCodeIsAuthenticated)

and update both call sites (the effectiveApiConfiguration expression and the handleGetStarted initial-state path) to pass zooCodeIsAuthenticated.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/welcome/WelcomeViewProvider.tsx` around lines 23 -
36, getWelcomeApiConfiguration currently calls
validateApiConfiguration(apiConfiguration) without passing the
zooCodeIsAuthenticated flag, so authenticated zoo-gateway configs get dropped
and fall back to DEFAULT_WELCOME_API_CONFIGURATION; update
getWelcomeApiConfiguration to accept a zooCodeIsAuthenticated boolean and pass
it as the 4th argument to validateApiConfiguration, and then update both places
that call getWelcomeApiConfiguration (the effectiveApiConfiguration expression
and the initial state path used in handleGetStarted) to thread the
zooCodeIsAuthenticated value through so validateApiConfiguration can correctly
treat zooSessionToken/authenticated zoo-gateway cases.
🧹 Nitpick comments (2)
src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts (1)

8-11: ⚡ Quick win

Cover the cached-token fallback path too.

Line 9 hardcodes getCachedZooCodeToken() to "", but this suite never verifies the fallback branch in src/api/providers/fetchers/zoo-gateway.ts that uses the cached token when zooSessionToken is omitted. A regression there would still pass all these tests. Please add a package-local unit test that overrides this mock to a non-empty token and asserts Authorization: Bearer <cached-token> is sent when only the auth-service fallback is available. As per coding guidelines, "Use package-local unit tests for pure logic, parsing, state transitions, validation, serialization, request construction, retry decisions, and error handling."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts` around lines 8 -
11, Add a new package-local unit test in
src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts that overrides the
mocked getCachedZooCodeToken() to return a non-empty token (e.g.,
"cached-token") and omits passing zooSessionToken to the request path exercised
by the zoo-gateway module; then assert that the outgoing request includes the
header "Authorization: Bearer cached-token". Target the code paths in
zoo-gateway (functions that construct the request using zooSessionToken fallback
to getCachedZooCodeToken) and use the existing vitest.mock for
../../../../services/zoo-code-auth to temporarily return the non-empty token for
this test, verifying the Authorization header is present and correctly
formatted.
webview-ui/src/utils/__tests__/validate.spec.ts (1)

254-286: ⚡ Quick win

Consider adding org allow-list coverage for zoo-gateway.

These tests verify the sign-in short-circuit but only use allowAllOrganization. Given the form-level early return in validateApiConfigurationExcludingModelErrors, a test asserting the expected behavior when zoo-gateway is restricted by a restrictiveOrganization would lock in the org-allow-list contract (and surface the gap flagged on validate.ts Lines 304-306).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/utils/__tests__/validate.spec.ts` around lines 254 - 286, Add
a test to validateApiConfigurationExcludingModelErrors that covers the org
allow-list behavior for the "zoo-gateway" provider by using the existing
restrictiveOrganization fixture (in addition to mockRouterModels and
ProviderSettings) so the form-level early return is exercised when the
organization disallows zoo-gateway; create a ProviderSettings with apiProvider:
"zoo-gateway" (with and without zooSessionToken) and assert the expected result
(undefined or a specific error) when restrictiveOrganization is passed instead
of allowAllOrganization to lock in the org-allow-list contract flagged around
validate.ts usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@webview-ui/src/i18n/locales/en/settings.json`:
- Around line 558-559: The validation message currently references a CTA that
doesn't match the button label; update the strings so the CTA and button copy
are identical: either change the sign-in validation message to use the exact
value of "signInButton" (the key signInButton) — e.g., "Sign in to Zoo Code" —
or change the signInButton value to match the quoted CTA used in the validation
text; ensure you update all localized copies (the signInButton and the
validation message keys such as signInDescription and the validation message
keys around the same area) so users are told to click the actual shown label.

In `@webview-ui/src/i18n/locales/zh-CN/settings.json`:
- Around line 566-567: The CTA in the instructions doesn't match the actual
button label; ensure the quoted CTA and the actual button label are identical by
updating the instructional copy to reference the exact value of the signInButton
key ("登录 Zoo Code") or vice versa—update either the instruction that currently
says 「登录」 to say 「登录 Zoo Code」 or change the signInButton value to "登录" so both
strings match; locate the text by the signInButton key and the instructional
string that mentions 「登录」 and make them identical.

In `@webview-ui/src/i18n/locales/zh-TW/settings.json`:
- Around line 581-582: The validation message currently references the button
label as 「登入」 but the actual button key signInButton is "登入 Zoo Code"; update
the validation text to use the exact signInButton string ("登入 Zoo Code") so the
UI labels match — locate the signInButton entry and the corresponding
validation/message string and make them identical (use the signInButton value
"登入 Zoo Code" in the validation message).

In `@webview-ui/src/utils/validate.ts`:
- Around line 304-306: The early return for apiConfiguration.apiProvider ===
"zoo-gateway" skips organization-level provider checks; move or add a call to
validateProviderAgainstOrganizationSettings(apiConfiguration.apiProvider, ...)
before that return and if it returns a PROVIDER_NOT_ALLOWED error, return that
error; only after the org check, allow the special-case early return for
zoo-gateway (so sign-in-specific handling in ZooGateway.tsx still occurs) and
leave the rest of getModelValidationError behavior unchanged.

---

Outside diff comments:
In `@webview-ui/src/components/welcome/WelcomeViewProvider.tsx`:
- Around line 23-36: getWelcomeApiConfiguration currently calls
validateApiConfiguration(apiConfiguration) without passing the
zooCodeIsAuthenticated flag, so authenticated zoo-gateway configs get dropped
and fall back to DEFAULT_WELCOME_API_CONFIGURATION; update
getWelcomeApiConfiguration to accept a zooCodeIsAuthenticated boolean and pass
it as the 4th argument to validateApiConfiguration, and then update both places
that call getWelcomeApiConfiguration (the effectiveApiConfiguration expression
and the initial state path used in handleGetStarted) to thread the
zooCodeIsAuthenticated value through so validateApiConfiguration can correctly
treat zooSessionToken/authenticated zoo-gateway cases.

---

Nitpick comments:
In `@src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts`:
- Around line 8-11: Add a new package-local unit test in
src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts that overrides the
mocked getCachedZooCodeToken() to return a non-empty token (e.g.,
"cached-token") and omits passing zooSessionToken to the request path exercised
by the zoo-gateway module; then assert that the outgoing request includes the
header "Authorization: Bearer cached-token". Target the code paths in
zoo-gateway (functions that construct the request using zooSessionToken fallback
to getCachedZooCodeToken) and use the existing vitest.mock for
../../../../services/zoo-code-auth to temporarily return the non-empty token for
this test, verifying the Authorization header is present and correctly
formatted.

In `@webview-ui/src/utils/__tests__/validate.spec.ts`:
- Around line 254-286: Add a test to
validateApiConfigurationExcludingModelErrors that covers the org allow-list
behavior for the "zoo-gateway" provider by using the existing
restrictiveOrganization fixture (in addition to mockRouterModels and
ProviderSettings) so the form-level early return is exercised when the
organization disallows zoo-gateway; create a ProviderSettings with apiProvider:
"zoo-gateway" (with and without zooSessionToken) and assert the expected result
(undefined or a specific error) when restrictiveOrganization is passed instead
of allowAllOrganization to lock in the org-allow-list contract flagged around
validate.ts usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 809d1b1c-e051-4062-9dde-7fe1564cb4e5

📥 Commits

Reviewing files that changed from the base of the PR and between f186c60 and babbe9e.

📒 Files selected for processing (29)
  • src/api/providers/fetchers/__tests__/zoo-gateway.spec.ts
  • webview-ui/src/components/settings/ApiOptions.tsx
  • webview-ui/src/components/settings/ModelPicker.tsx
  • webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx
  • webview-ui/src/components/settings/constants.ts
  • webview-ui/src/components/settings/providers/ZooGateway.tsx
  • webview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsx
  • webview-ui/src/components/settings/providers/index.ts
  • webview-ui/src/components/welcome/WelcomeViewProvider.tsx
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/pl/settings.json
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/ru/settings.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
  • webview-ui/src/utils/__tests__/validate.spec.ts
  • webview-ui/src/utils/validate.ts

Comment thread webview-ui/src/i18n/locales/en/settings.json
Comment thread webview-ui/src/i18n/locales/zh-CN/settings.json
Comment thread webview-ui/src/i18n/locales/zh-TW/settings.json
Comment thread webview-ui/src/utils/validate.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@webview-ui/src/i18n/locales/fr/settings.json`:
- Line 912: Change the informal French register in validation.zooGatewaySignIn
to match the formal register used by providers.zooGateway.signInDescription;
replace "Connecte-toi à Zoo Code pour utiliser Zoo Gateway." with the formal
phrasing (e.g., "Connectez-vous à Zoo Code pour utiliser Zoo Gateway.") so both
keys use "vous" for consistency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d99f9f3c-805c-400c-8a54-3b3d00a7d90a

📥 Commits

Reviewing files that changed from the base of the PR and between babbe9e and 26ecbd7.

📒 Files selected for processing (22)
  • webview-ui/src/components/settings/ApiOptions.tsx
  • webview-ui/src/components/settings/utils/providerModelConfig.ts
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/pl/settings.json
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/ru/settings.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
  • webview-ui/src/utils/__tests__/validate.spec.ts
  • webview-ui/src/utils/validate.ts
✅ Files skipped from review due to trivial changes (9)
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/ru/settings.json
🚧 Files skipped from review as they are similar to previous changes (9)
  • webview-ui/src/i18n/locales/pl/settings.json
  • webview-ui/src/utils/tests/validate.spec.ts
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/i18n/locales/ja/settings.json

Comment thread webview-ui/src/i18n/locales/fr/settings.json Outdated
@JamesRobert20 JamesRobert20 requested review from edelauna and taltas June 2, 2026 15:51
James Mtendamema and others added 15 commits June 2, 2026 18:44
Co-authored-by: Cursor <cursoragent@cursor.com>
… fetch

- Stop reassigning RouterProvider.client; thread Zoo enrichment headers
  through openAiHeaders so a single OpenAI client is used.
- Replace npm_package_version (never populated at extension runtime)
  with Package.version from the shared package shim.
- Default the model list to [] on a structurally broken response so we
  log and recover instead of crashing on response.data.data being
  undefined.
- Bypass inFlightRefresh de-duplication for zoo-gateway: a refresh
  triggered after sign-out/sign-in must not return the previous user's
  in-flight response.
- Add fetcher unit tests covering auth header, timeout, error
  redaction, and bad-response handling.

Co-authored-by: Cursor <cursoragent@cursor.com>
The downstream stack (settings-ui) calls getCachedZooCodeToken and
clearZooCodeToken from the auth handler. CI on stacked PRs merges base
into head so this spec runs against the cached-token-aware handler;
expand the auth module mock so the auth guard test exercises the real
throw path instead of vitest's missing-mock-export error.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Resolve ModelPicker serviceUrl from zooCodeBaseUrl so staging/dev
  environments link to the matching dashboard.
- Fall back to getCachedZooCodeToken() in the handler and model fetcher
  when the profile has not been seeded yet (auth before webview open).

Co-authored-by: Cursor <cursoragent@cursor.com>
…-lockfile installs

Co-authored-by: Cursor <cursoragent@cursor.com>
…ch 'free' search hint dropped on rebase

Co-authored-by: Cursor <cursoragent@cursor.com>
… 4.5

Resolves Sonnet 4.5 from the gateway model catalog instead of a static Vercel slug so test (Bedrock) and live accounts both get a valid default. Reassigns stale profile model IDs when they are not in the catalog.

Co-authored-by: Cursor <cursoragent@cursor.com>
Exports pickZooGatewayDefaultModelId so the helper is unit-testable and adds
component tests for the auto-default useEffect (no-op while catalog loads,
auto-pick on empty profile, repair stale id, no-op when valid).

Co-authored-by: Cursor <cursoragent@cursor.com>
…rings

Co-authored-by: Cursor <cursoragent@cursor.com>
… auth

Co-authored-by: Cursor <cursoragent@cursor.com>
Move the zoo-gateway sign-in error out of the shared form-validation effect
in ApiOptions and into ZooGateway.tsx, where it renders inline via
ApiErrorMessage. ApiOptions can then drop zooCodeIsAuthenticated from its
useEffect dependency list, and validateApiConfigurationExcludingModelErrors
short-circuits zoo-gateway entirely.

Also rename the inline isSonnet45ModelId helper to isClaudeSonnetModelId
and let pickZooGatewayDefaultModelId express the version-priority order
directly, so the helper has no version baked into its name.

Co-authored-by: Cursor <cursoragent@cursor.com>
The settings-form short-circuit for zoo-gateway also bypassed the
organization PROVIDER_NOT_ALLOWED check, so a workspace that disallows
zoo-gateway could not surface that error. Scope the short-circuit to
the keys/sign-in check only and let the org allowlist check run for
every provider.

Drop the quoted CTA from zooGatewaySignIn in all 18 locales: the
sign-in button is rendered immediately below the inline error, so a
duplicate label was just a drift hazard.

Co-authored-by: Cursor <cursoragent@cursor.com>
…Options

Lift the inline PROVIDER_MODEL_CONFIG map and the docs-slug lookup out
of ApiOptions.tsx into webview-ui/src/components/settings/utils/providerModelConfig.ts
behind getProviderModelConfig and getProviderDocsSlug helpers. ApiOptions
now reads provider-specific model fields, defaults, and docs slugs through
those helpers, leaving the component focused on rendering.

Co-authored-by: Cursor <cursoragent@cursor.com>
validation.zooGatewaySignIn used "Connecte-toi" while
providers.zooGateway.signInDescription uses "Connectez-vous".
Use vous consistently across both strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
@JamesRobert20 JamesRobert20 force-pushed the feat/zoo-gateway-settings-ui branch from 5aa42cc to 2fbf902 Compare June 3, 2026 00:49
@JamesRobert20 JamesRobert20 added this pull request to the merge queue Jun 3, 2026
Merged via the queue into main with commit f9c9c09 Jun 3, 2026
10 checks passed
@JamesRobert20 JamesRobert20 deleted the feat/zoo-gateway-settings-ui branch June 3, 2026 01:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants